package com.rupertjones.globalcron.web.service;

import com.rupertjones.globalcron.domain.JobDescriptor;
import com.rupertjones.globalcron.domain.JobDescriptorDAO;
import com.rupertjones.globalcron.domain.JobExecutionLog;
import com.rupertjones.globalcron.domain.JobExecutionLogDAO;
import com.rupertjones.globalcron.web.munin.MuninGraphConfig;
import com.rupertjones.globalcron.web.munin.MuninGraphValueConfig;
import com.rupertjones.globalcron.web.munin.MuninReport;
import com.rupertjones.globalcron.web.munin.MuninResult;
import com.rupertjones.globalcron.web.munin.MuninResults;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>&copy Rupert Jones 2012</p>
 *
 * @author rup
 */
@Service
public class ExecutionsMuninReport implements MuninReport {

    @Autowired
    private JobExecutionLogDAO jobExecutionLogDAO;

    @Autowired
    private JobDescriptorDAO jobDescriptorDAO;

    @Override
    public MuninGraphConfig getConfig() {
        MuninGraphConfig config = new MuninGraphConfig();
        config.setCategory("global-cron");
        config.setTitle("Executions");
        config.setVerticalLabel("Number of executions");

        int count = 1;

        for (JobDescriptor job : jobDescriptorDAO.findAll()){
            MuninGraphValueConfig drawConfig = new MuninGraphValueConfig();
            drawConfig.setValueKey(job.getKey());
            drawConfig.setValueConfig("draw");
            drawConfig.setConfigValue((count == 1 ? "AREA" : "STACK"));
            drawConfig.setObject(job);
            config.addValueConfig(drawConfig);

            MuninGraphValueConfig labelConfig = new MuninGraphValueConfig();
            labelConfig.setValueKey(job.getKey());
            labelConfig.setValueConfig("label");
            labelConfig.setConfigValue(job.getKey());
            labelConfig.setObject(job);
            config.addValueConfig(labelConfig);
            count++;
        }

        return config;
    }

    @Override
    public MuninResults getResults() {
        DateTime then = new DateTime().minusMinutes(5);
        Collection<JobExecutionLog> logs = jobExecutionLogDAO.findAllSince(then);
        Map<String, AtomicInteger> record = new HashMap<String, AtomicInteger>();

        for (JobExecutionLog log : logs) {
            JobDescriptor job = log.getJob();
            if(record.containsKey(job.getKey())) {
                record.get(job.getKey()).getAndIncrement();
            } else {
                record.put(job.getKey(), new AtomicInteger(1));
            }
        }

        MuninResults results = new MuninResults();
        for (JobDescriptor job : jobDescriptorDAO.findAll()){
            MuninResult result = new MuninResult();
            result.setKey(job.getKey());
            if(record.containsKey(job.getKey())) {
                AtomicInteger count = record.get(job.getKey());
                result.setValue(String.valueOf(count.get()));
            } else {
                result.setValue("0");
            }
            results.add(result);
        }
        return results;
    }
}
